package com.lfy.pay.zfb;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.AlipayRequest;
import com.alipay.api.AlipayResponse;
import com.alipay.api.domain.AlipayTradePrecreateModel;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import javax.annotation.Resource;

/**
 * 支付宝支付API
 * @author lvfeiyang
 */
@Slf4j
public class AlipayApi implements ApplicationContextAware {

    private static AlipayClient alipayClient;

    private static ZfbOptions zfbOptions;

    /**
     * 根据配置的类型，选择执行请求的接口
     */
    public static <T extends AlipayResponse> T doExecute(AlipayRequest<T> request) throws AlipayApiException {
        if (ZfbConstant.CERT.equals(zfbOptions.getType())) {
            return certificateExecute(request);
        } else {
            return execute(request);
        }
    }

    public static <T extends AlipayResponse> T doExecute(AlipayClient alipayClient,  AlipayRequest<T> request) throws AlipayApiException {
        if (alipayClient == null) {
            throw new IllegalStateException("aliPayClient 未被初始化");
        }
        if (ZfbConstant.CERT.equals(zfbOptions.getType())) {
            return certificateExecute(alipayClient, request);
        } else {
            return execute(alipayClient, request);
        }
    }

    public static <T extends AlipayResponse> T doExecute(AlipayRequest<T> request, String authToken) throws AlipayApiException {
        if (ZfbConstant.CERT.equals(zfbOptions.getType())) {
            return certificateExecute(request, authToken);
        } else {
            return execute(request, authToken);
        }
    }


    public static <T extends AlipayResponse> T doExecute(AlipayClient alipayClient, AlipayRequest<T> request, String authToken) throws AlipayApiException {
        if (alipayClient == null) {
            throw new IllegalStateException("aliPayClient 未被初始化");
        }
        if (ZfbConstant.CERT.equals(zfbOptions.getType())) {
            return certificateExecute(alipayClient, request, authToken);
        } else {
            return execute(alipayClient, request, authToken);
        }
    }

    /**
     * ======================================================公钥支付封装===========================================================
     */
    public static <T extends AlipayResponse> T execute(AlipayRequest<T> request) throws AlipayApiException {
        return alipayClient.execute(request);
    }


    public static <T extends AlipayResponse> T execute(AlipayClient alipayClient, AlipayRequest<T> request) throws AlipayApiException {
        if (alipayClient == null) {
            throw new IllegalStateException("aliPayClient 未被初始化");
        }
        return alipayClient.execute(request);
    }

    public static <T extends AlipayResponse> T execute(AlipayRequest<T> request, String authToken) throws AlipayApiException {
        return alipayClient.execute(request, authToken);
    }

    public static <T extends AlipayResponse> T execute(AlipayClient alipayClient, AlipayRequest<T> request, String authToken) throws AlipayApiException {
        if (alipayClient == null) {
            throw new IllegalStateException("aliPayClient 未被初始化");
        }
        return alipayClient.execute(request, authToken);
    }

    public static <T extends AlipayResponse> T execute(AlipayRequest<T> request, String accessToken, String appAuthToken) throws AlipayApiException {
        return alipayClient.execute(request, accessToken, appAuthToken);
    }

    public static <T extends AlipayResponse> T execute(AlipayClient alipayClient, AlipayRequest<T> request, String accessToken, String appAuthToken) throws AlipayApiException {
        if (alipayClient == null) {
            throw new IllegalStateException("aliPayClient 未被初始化");
        }
        return alipayClient.execute(request, accessToken, appAuthToken);
    }

    /**
     * ======================================================证书支付封装===========================================
     */
    public static <T extends AlipayResponse> T certificateExecute(AlipayRequest<T> request) throws AlipayApiException {
        return alipayClient.certificateExecute(request);
    }

    public static <T extends AlipayResponse> T certificateExecute(AlipayClient alipayClient, AlipayRequest<T> request) throws AlipayApiException {
        if (alipayClient == null) {
            throw new IllegalStateException("aliPayClient 未被初始化");
        }
        return alipayClient.certificateExecute(request);
    }

    public static <T extends AlipayResponse> T certificateExecute(AlipayRequest<T> request, String authToken) throws AlipayApiException {
        return alipayClient.certificateExecute(request, authToken);
    }

    public static <T extends AlipayResponse> T certificateExecute(AlipayClient alipayClient, AlipayRequest<T> request, String authToken) throws AlipayApiException {
        if (alipayClient == null) {
            throw new IllegalStateException("aliPayClient 未被初始化");
        }
        return alipayClient.certificateExecute(request, authToken);
    }

    /**
     * =======================================================网页支付封装======================================================
     */
    public static <T extends AlipayResponse> T pageExecute(AlipayRequest<T> request) throws AlipayApiException {
        return alipayClient.pageExecute(request);
    }

    public static <T extends AlipayResponse> T pageExecute(AlipayClient alipayClient, AlipayRequest<T> request) throws AlipayApiException {
        if (alipayClient == null) {
            throw new IllegalStateException("aliPayClient 未被初始化");
        }
        return alipayClient.pageExecute(request);
    }

    public static <T extends AlipayResponse> T pageExecute(AlipayRequest<T> request, String method) throws AlipayApiException {
        return alipayClient.pageExecute(request, method);
    }

    public static <T extends AlipayResponse> T pageExecute(AlipayClient alipayClient, AlipayRequest<T> request, String method) throws AlipayApiException {
        if (alipayClient == null) {
            throw new IllegalStateException("aliPayClient 未被初始化");
        }
        return alipayClient.pageExecute(request, method);
    }
    /**
     * ======================================================扫码支付================================================================================
     */
    /**
     * 统一收单线下交易预创建 <br>
     * 适用于：扫码支付等 <br>
     *
     * @param alipayClient {@link AlipayClient}
     * @param model        {@link AlipayTradePrecreateModel}
     * @param notifyUrl    异步通知URL
     * @param appAuthToken 应用授权token
     * @return {@link AlipayTradePrecreateResponse}
     * @throws AlipayApiException 支付宝 Api 异常
     */
    public static AlipayTradePrecreateResponse imageCreatePayToResponse(AlipayClient alipayClient, AlipayTradePrecreateModel model, String notifyUrl, String appAuthToken) throws AlipayApiException {
        AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
        request.setBizModel(model);
        request.setNotifyUrl(notifyUrl);
        return doExecute(alipayClient, request, appAuthToken);
    }
    public static AlipayTradePrecreateResponse imageCreatePayToResponse(AlipayTradePrecreateModel model, String notifyUrl, String appAuthToken) throws AlipayApiException {
        AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
        request.setBizModel(model);
        request.setNotifyUrl(notifyUrl);
        return doExecute(alipayClient, request, appAuthToken);
    }
    public static AlipayTradePrecreateResponse imageCreatePayToResponse( AlipayTradePrecreateModel model) throws AlipayApiException {
        AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
        request.setBizModel(model);
        return doExecute(request);
    }
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        try {
            alipayClient = applicationContext.getBean(AlipayClient.class);
            zfbOptions = applicationContext.getBean(ZfbOptions.class);
            log.info("alipayApi client and zfbOptions  initialized");
        } catch (NoSuchBeanDefinitionException e) {
            throw new IllegalStateException("in alipayApi client or zfbOptions Bean not found in ApplicationContext", e);
        }
    }
}
